home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 24
/
Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso
/
Aminet
/
dev
/
c
/
vbcc.lha
/
vbcc
/
flow.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-12-30
|
22KB
|
527 lines
/* $VER: vbcc (flow.c) V0.4 */
/* Generierung des FLussgraphs und Optimierungen des Kontrollflusses */
#include "opt.h"
static char FILE_[]=__FILE__;
int bvcmp(unsigned char *dest,unsigned char *src,size_t len)
/* vergleicht zwei Bitvektoren */
{
for(;len>0;len--)
if(*dest++!=*src++) return(0);
return(1);
}
void bvunite(unsigned char *dest,unsigned char *src,size_t len)
/* berechnet Vereinigung zweier Bitvektoren */
{
for(;len>0;len--)
*dest++|=*src++;
}
void bvintersect(unsigned char *dest,unsigned char *src,size_t len)
/* berechnet Durchschnitt zweier Bitvektoren */
{
for(;len>0;len--)
*dest++&=*src++;
}
void bvdiff(unsigned char *dest,unsigned char *src,size_t len)
/* berechnet 'Differenz' zweier Bitvektoren */
{
for(;len>0;len--)
*dest++&=~(*src++);
}
unsigned int basic_blocks;
struct flowgraph *construct_flowgraph(void)
/* entfernt ueberfluessige Labels und erzeugt Flussgraph */
{
struct IC *p;
int firstl=lastlabel,lcnt=label-firstl,currentl,i,code,l;
int *iseq=mymalloc(lcnt*sizeof(int));
int *used=mymalloc(lcnt*sizeof(int));
struct flowgraph **lg=mymalloc(lcnt*sizeof(struct flowgraph *));
struct flowgraph *g=mymalloc(sizeof(struct flowgraph)),*fg=g;
g->start=first_ic;g->in=0;g->branchout=0;g->loopend=0;
for(i=0;i<lcnt;i++) {iseq[i]=used[i]=0;lg[i]=0;}
currentl=0;firstl++;
/* Diese Schleife entfernt alle Labels, die mit anderen */
/* uebereinstimmen, merkt sich das und kennzeichnet alle */
/* Labels, die benutzt werden. */
/* Ausserdem wird der Flussgraph teilweise aufgebaut. */
if(DEBUG&1024) {puts("construct_flowgraph(): loop1");/*scanf("%d",&i);*/}
i=1;g->index=i;
for(p=first_ic;p;){
code=p->code;
if(code>=BEQ&&code<=BRA){
l=p->typf;
/* als used markieren; falls aequivalent, das erste markieren */
if(iseq[l-firstl]) used[iseq[l-firstl]-firstl]=1;
else used[l-firstl]=1;
/* Flussgraph beenden und evtl. naechsten Knoten erzeugen */
g->end=p;
if(p->next){
g->normalout=mymalloc(sizeof(struct flowgraph));
g->normalout->in=mymalloc(sizeof(struct flowlist));
g->normalout->in->next=0;
g->normalout->in->graph=g;
g=g->normalout;
g->start=p->next;
g->branchout=0;
g->loopend=0;
g->index=++i;
}else g->normalout=0;
currentl=0;p=p->next;continue;
}
if(code==ALLOCREG||code==FREEREG){p=p->next; continue;}
if(code!=LABEL){currentl=0;p=p->next;continue;}
/* ist ein Label */
l=p->typf;
if(currentl){
struct IC *m;
iseq[l-firstl]=currentl;
if(used[l-firstl]) used[currentl-firstl]=1;
m=p;p=p->next;
remove_IC(m);
continue;
/* if(DEBUG&1024) printf("label %d==%d\n",l,iseq[l-firstl]);*/
}else{
currentl=l;
if(g->start!=p){
g->end=p->prev;
g->normalout=mymalloc(sizeof(struct flowgraph));
g->normalout->in=mymalloc(sizeof(struct flowlist));
g->normalout->in->next=0;
g->normalout->in->graph=g;
g=g->normalout;
g->start=p;
g->branchout=0;
g->loopend=0;
g->index=++i;
}else g->branchout=0;
lg[l-firstl]=g;
}
p=p->next;
}
g->end=last_ic;g->normalout=g->branchout=0;
if(DEBUG&1024) printf("%d basic blocks\n",i);
basic_blocks=i;
/* if(DEBUG&1024) for(i=firstl;i<=lcnt;i++) printf("L%d used: %d\n",i,used[i-firstl]);*/
/* Diese Schleife entfernt alle nicht benutzten Labels und biegt alle */
/* Branches auf aequivalente Labels um. */
if(DEBUG&1024) {puts("construct_flowgraph(): loop2");/*scanf("%d",&i);*/}
g=fg;
while(g){
int flag=0;struct flowlist *lp;
/* printf("g=%p\n",(void *)g);*/
g->av_in=g->av_out=g->av_gen=g->av_kill=0;
g->rd_in=g->rd_out=g->rd_gen=g->rd_kill=0;
g->ae_in=g->ae_out=g->ae_gen=g->ae_kill=0;
g->cp_in=g->cp_out=g->cp_gen=g->cp_kill=0;
p=g->start;
while(p&&!flag){
/* pric2(stdout,p);*/
code=p->code;
if(code>=BEQ&&code<=BRA){
l=p->typf;
if(iseq[l-firstl]) p->typf=l=iseq[l-firstl];
/* in Flussgraph eintragen */
g->branchout=lg[l-firstl];
if(!lg[l-firstl]) ierror(0);
lp=lg[l-firstl]->in;
/* das hier sollte man noch schoener machen */
if(!lp){
lg[l-firstl]->in=mymalloc(sizeof(struct flowlist));
lg[l-firstl]->in->next=0;
lg[l-firstl]->in->graph=g;
}else{
while(lp&&lp->next) lp=lp->next;
lp->next=mymalloc(sizeof(struct flowlist));
lp->next->next=0;
lp->next->graph=g;
}
}
/* if(code==LABEL&&!used[p->typf-firstl]) remove_IC(p);*/
if(p==g->end) flag=1;
p=p->next;
}
g=g->normalout;
}
/* Unbenutzte Labels entfernen und Bloecke verbinden */
if(DEBUG&1024) {puts("construct_flowgraph(): loop3");/*scanf("%d",&i);*/}
for(g=fg;g;g=g->normalout){
if(g->end&&(g->end->code<BEQ||g->end->code>BRA)){
struct flowgraph *next=g->normalout;struct flowlist *lp;
if(next&&next->start&&next->start->code==LABEL&&!used[next->start->typf-firstl]){
if(next->end!=next->start) g->end=next->end;
g->normalout=next->normalout;
g->branchout=next->branchout;
free(next->in); /* darf eigentlich nur einen Vorgaenger haben */
/* in im Nachfolgeknoten auf den ersten der beiden setzen */
if(next->normalout&&next->normalout->in) next->normalout->in->graph=g;
/* in im Ziel von next->branchout auf den ersten setzen */
if(next->branchout){
lp=next->branchout->in;
while(1){
if(lp->graph==next){ lp->graph=g;break;}
lp=lp->next;if(!lp) ierror(0);
}
}
if(DEBUG&1024){ printf("unused label deleted:\n");pric2(stdout,next->start);}
remove_IC(next->start);
free(next);
}
}
/* unbenutzte Labels entfernen */
if(g->start&&g->start->code==LABEL&&!used[g->start->typf-firstl])
remove_IC_fg(g,g->start);
}
free(iseq);
free(used);
return(fg);
}
void print_flowgraph(struct flowgraph *g)
/* Gibt Flussgraph auf Bildschirm aus */
{
static int dontprint=0;
int flag,i;struct flowlist *lp;struct IC *ip;
if(dontprint) return;
puts("print_flowgraph()");scanf("%d",&i);
if(i<0){dontprint=1;return;}
if(!i) return;
while(g){
printf("\nBasic Block nr. %d\n",g->index);
printf("\tin from ");
lp=g->in;
while(lp){if(lp->graph) printf("%d ",lp->graph->index);lp=lp->next;}
printf("\n\tout to %d %d\n",g->normalout?g->normalout->index:0,g->branchout?g->branchout->index:0);
if(g->loopend) printf("head of a loop ending at block %d\n",g->loopend->index);
if(i&2){
printf("av_gen:\n"); print_av(g->av_gen);
printf("av_kill:\n"); print_av(g->av_kill);
printf("av_in:\n"); print_av(g->av_in);
printf("av_out:\n"); print_av(g->av_out);
}
if(i&4){
printf("rd_gen:\n"); print_rd(g->rd_gen);
printf("rd_kill:\n"); print_rd(g->rd_kill);
printf("rd_in:\n"); print_rd(g->rd_in);
printf("rd_out:\n"); print_rd(g->rd_out);